from flask import Flask, render_template_string, request, send_from_directory, Response
from flask_socketio import SocketIO, emit
import logging
from LOBOROBOT import LOBOROBOT
import json
import os
from camara import Camera

# 设置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 初始化机器人
robot = LOBOROBOT()

# 初始化摄像头
camera = Camera()

# 初始化Flask应用
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'

# 初始化SocketIO
socketio = SocketIO(app, cors_allowed_origins="*")

# 读取controller.html内容
try:
    with open('controller.html', 'r', encoding='utf-8') as f:
        controller_html = f.read()
except FileNotFoundError:
    controller_html = "<h1>Controller file not found</h1>"

@app.route('/')
def index():
    """提供遥控器页面"""
    return render_template_string(controller_html)

@app.route('/css/<path:filename>')
def css_files(filename):
    """提供CSS静态文件"""
    return send_from_directory('css', filename)

@app.route('/js/<path:filename>')
def js_files(filename):
    """提供JS静态文件（如果需要）"""
    return send_from_directory('js', filename)

@app.route('/video_feed')
def video_feed():
    """视频流路由"""
    logger.info("收到视频流请求")
    try:
        # 启动摄像头
        if not camera.start():
            logger.error("无法启动摄像头")
            # 返回错误图像
            import numpy as np
            import cv2
            frame = np.zeros((480, 640, 3), dtype=np.uint8)
            cv2.putText(frame, 'Camera Error', (50, 240), 
                       cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
            cv2.putText(frame, 'Failed to start camera', (50, 280), 
                       cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 1)
            ret, buffer = cv2.imencode('.jpg', frame)
            if ret:
                return Response(b'--frame\r\n'
                                b'Content-Type: image/jpeg\r\n\r\n' + buffer.tobytes() + b'\r\n',
                                mimetype='multipart/x-mixed-replace; boundary=frame')
            else:
                return "无法生成错误图像", 500
        
        # 返回视频流响应
        return Response(camera.gen_frames(),
                        mimetype='multipart/x-mixed-replace; boundary=frame')
    except Exception as e:
        logger.error(f"视频流发生错误: {e}")
        return f"视频流错误: {str(e)}", 500

@socketio.on('connect')
def handle_connect():
    """处理客户端连接"""
    logger.info('客户端连接')

@socketio.on('disconnect')
def handle_disconnect():
    """处理客户端断开连接"""
    logger.info('客户端断开连接')
    # 客户端断开连接时不停止摄像头，因为可能有多个客户端

@socketio.on('command')
def handle_command(command):
    """处理来自客户端的命令"""
    logger.info(f'收到命令: {command}')
    
    # 如果命令是字符串，转换为字典
    if isinstance(command, str):
        try:
            command = json.loads(command)
        except:
            command = {'type': 'movement', 'command': command, 'speed': 50}
    
    # 处理不同类型的命令
    if command['type'] == 'movement':
        handle_movement_command(command)
    elif command['type'] == 'servo':
        handle_servo_command(command)
    elif command['type'] == 'camera':
        handle_camera_command(command)
    
    # 发送确认消息回客户端
    emit('response', {'status': 'success', 'command': command})

def handle_movement_command(command):
    """处理移动命令"""
    cmd = command['command']
    speed = command.get('speed', 50)
    
    # 根据收到的命令控制机器人
    if cmd == "forward":
        robot.t_up(speed, 0)  # 前进
        logger.info(f"机器人前进，速度: {speed}")
    elif cmd == "backward":
        robot.t_down(speed, 0)  # 后退
        logger.info(f"机器人后退，速度: {speed}")
    elif cmd == "move_left":
        robot.moveLeft(speed, 0)  # 左移
        logger.info(f"机器人左移，速度: {speed}")
    elif cmd == "move_right":
        robot.moveRight(speed, 0)  # 右移
        logger.info(f"机器人右移，速度: {speed}")
    elif cmd == "turn_left":
        robot.turnLeft(speed, 0)  # 左转
        logger.info(f"机器人左转，速度: {speed}")
    elif cmd == "turn_right":
        robot.turnRight(speed, 0)  # 右转
        logger.info(f"机器人右转，速度: {speed}")
    elif cmd == "forward_left":
        robot.forward_Left(speed, 0)  # 前左斜
        logger.info(f"机器人前左斜，速度: {speed}")
    elif cmd == "forward_right":
        robot.forward_Right(speed, 0)  # 前右斜
        logger.info(f"机器人前右斜，速度: {speed}")
    elif cmd == "backward_left":
        robot.backward_Left(speed, 0)  # 后左斜
        logger.info(f"机器人后左斜，速度: {speed}")
    elif cmd == "backward_right":
        robot.backward_Right(speed, 0)  # 后右斜
        logger.info(f"机器人后右斜，速度: {speed}")
    elif cmd == "stop":
        robot.t_stop(0)  # 停止
        logger.info("机器人停止")

def handle_servo_command(command):
    """处理舵机命令"""
    channel = command['channel']
    angle = command['angle']
    
    # 设置舵机角度
    robot.set_servo_angle(channel, angle)
    logger.info(f"设置舵机通道 {channel} 角度 {angle}°")

def handle_camera_command(command):
    """处理摄像头命令"""
    action = command.get('action')
    if action == 'start':
        success = camera.start()
        if success:
            logger.info("启动摄像头成功")
        else:
            logger.error("启动摄像头失败")
    elif action == 'stop':
        # 注意：这里我们不真正停止摄像头，因为可能有其他客户端在使用
        logger.info("收到停止摄像头命令（但保持摄像头运行以支持多客户端）")

if __name__ == '__main__':
    logger.info("服务器启动，监听端口 5000")
    logger.info("可以通过 http://localhost:5000 访问遥控器页面")
    logger.info("树莓派摄像头支持已启用")
    try:
        socketio.run(app, host='0.0.0.0', port=5000, debug=False)
    finally:
        camera.stop()